package com.tsd.wxpay;

import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.tsd.core.datasource.DataSourceContextHolder;
import com.tsd.core.utils.HlpUtils;
import com.tsd.system.service.WxSettingService;
import com.tsd.system.vo.WxPaySetting;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 从sys_setting表中获取的微信支付配置
 */
@Component
public class WxPayConfig4SysSettingService {

    public static final String PAID_TYPE_WX_GZH = "wx_gzh";
    public static final String PAID_TYPE_WX_XCX = "wx_xcx";
    public static final String PAID_TYPE_H5 = "h5";

    private static final List<String> PAID_TYPE_LIST;

    @Resource
    private WxSettingService wxSettingService;

    /**
     * 各个参数配置的缓存，key为account_set_sid
     */
    private static final Map<String, WxPayConfig> WX_PAY_CONFIG_MAP;

    static {
        WX_PAY_CONFIG_MAP = new ConcurrentHashMap<>();
        PAID_TYPE_LIST = new ArrayList<>();
        PAID_TYPE_LIST.add(PAID_TYPE_WX_GZH);
        PAID_TYPE_LIST.add(PAID_TYPE_WX_XCX);
        PAID_TYPE_LIST.add(PAID_TYPE_H5);
    }

    public List<String> getPaidTypeList() {
        return PAID_TYPE_LIST;
    }

    /**
     * 获取微信支付配置
     *
     * @return
     * @throws Exception
     */
    public WxPayConfig getWxPayConfig(WxPaySetting wxPaySetting) throws Exception {
        String targetType = DataSourceContextHolder.getDataSourceType();
        WxPayConfig payConfig = WX_PAY_CONFIG_MAP.get(targetType);
        if (payConfig == null) {
            if (wxPaySetting == null) {
                wxPaySetting = wxSettingService.getWxPaySetting();
            }
            if (wxPaySetting == null) {
                return null;
            }
            payConfig = new WxPayConfig();
            payConfig.setMchId(wxPaySetting.getWxpay_mch_id());
            payConfig.setMchKey(wxPaySetting.getWxpay_mch_key());
            payConfig.setNotifyUrl(wxPaySetting.getWxpay_notify_url());
            payConfig.setKeyPath(wxPaySetting.getWxpay_key_path());
            payConfig.setTradeType(WxPayConstants.TradeType.JSAPI);
            payConfig.setSignType(WxPayConstants.SignType.MD5);
            if (!HlpUtils.isEmpty(payConfig.getAppId()) &&
                    !HlpUtils.isEmpty(payConfig.getMchId()) &&
                    !HlpUtils.isEmpty(payConfig.getMchKey())) {
                WX_PAY_CONFIG_MAP.put(targetType, payConfig);
            }
        }
        return payConfig;
    }

    /**
     * 获取微信支付配置
     *
     * @param bizActionUrl
     * @return
     * @throws Exception
     */
    public WxPayConfig getWxPayConfig(WxPaySetting wxPaySetting, String bizActionUrl) throws Exception {
        WxPayConfig src = this.getWxPayConfig(wxPaySetting);
        WxPayConfig wxPayConfig = new WxPayConfig();
        copyItem(src, wxPayConfig);
        String url = wxPayConfig.getNotifyUrl();
        if (!HlpUtils.isEmpty(url)) {
            if (!url.endsWith("/")) {
                url = url + "/";
            }
            if (!HlpUtils.isEmpty(bizActionUrl)) {
                if (bizActionUrl.startsWith("/")) {
                    bizActionUrl = bizActionUrl.substring(1);
                }
                url = url + bizActionUrl;
            }
        } else {
            url = bizActionUrl;
        }
        wxPayConfig.setNotifyUrl(url);
        return wxPayConfig;
    }

    private void copyItem(WxPayConfig src, WxPayConfig payConfig) {
        payConfig.setAppId(src.getAppId());
        payConfig.setMchId(src.getMchId());
        payConfig.setMchKey(src.getMchKey());
        payConfig.setNotifyUrl(src.getNotifyUrl());
        payConfig.setKeyPath(src.getKeyPath());
        payConfig.setTradeType(src.getTradeType());
        payConfig.setSignType(src.getSignType());
    }

    /**
     * 获取微信支付配置
     *
     * @param bizActionUrl
     * @return
     * @throws Exception
     */
    public WxPaySetting getWxPaySetting(String bizActionUrl) throws Exception {
        WxPaySetting setting = wxSettingService.getWxPaySetting();
        WxPayConfig config = this.getWxPayConfig(setting, bizActionUrl);
        setting.setConfig(config);
        return setting;
    }

    /**
     * 清除某个配置缓存
     *
     * @param targetType
     */
    public void clearWxPayConfig(String targetType) {
        WX_PAY_CONFIG_MAP.remove(targetType);
    }

    /**
     * 更新微信支付的通知URL，以便适应不同业务的通知需要
     *
     * @param wxPayConfig
     * @param bizActionUrl
     */
    public void updateNotifyUrl4Biz(WxPayConfig wxPayConfig, String bizActionUrl) {
        String url = wxPayConfig.getNotifyUrl();
        if (url != null) {
            if (!url.endsWith("/")) {
                url = url + "/";
            }
            if (bizActionUrl != null) {
                if (bizActionUrl.startsWith("/")) {
                    bizActionUrl = bizActionUrl.substring(1);
                }
                url = url + bizActionUrl;
            }
        } else {
            url = bizActionUrl;
        }
        wxPayConfig.setNotifyUrl(url);
    }
}
